
#define MILLIS_PER_MIN 60100 // 每分钟毫秒数

#define ROTATION_PERIOD_IN_MSEC 10000//旋转周期 yxc：阈值

// 电机参数
#define STEPS_PER_ROTATION 4096 // 电机单步旋转
#define RATIO 5 // 每次旋转时间

#define LAP 65536  // 参数

// 等待步进电机一步走完时间
int delaytime = 30;

//UNL控制芯片接口 
int port[4] = {7, 6, 5, 4};


// 步进电机控制顺序
int seq[8][4] = {
  {  LOW, HIGH, HIGH,  LOW},
  {  LOW,  LOW, HIGH,  LOW},
  {  LOW,  LOW, HIGH, HIGH},
  {  LOW,  LOW,  LOW, HIGH},
  { HIGH,  LOW,  LOW, HIGH},
  { HIGH,  LOW,  LOW,  LOW},
  { HIGH, HIGH,  LOW,  LOW},
  {  LOW, HIGH,  LOW,  LOW}
};

void rotate(int step) {
  static int phase = 0;
  int i, j;
  int delta = (step > 0) ? 1 : 7;
  step = (step > 0) ? step : -step;
  for(j = 0; j < step; j++) {
    phase = (phase + delta) % 8;
    for(i = 0; i < 4; i++) {
      digitalWrite(port[i], seq[phase][i]);
    }
    delay(delaytime);
  }
  // 停止旋转
  for(i = 0; i < 4; i++) {
    digitalWrite(port[i], LOW);
  }
}
//定义数字输出端口
void setup() {
  pinMode(port[0], OUTPUT);
  pinMode(port[1], OUTPUT);
  pinMode(port[2], OUTPUT);
  pinMode(port[3], OUTPUT);
  pinMode(16, INPUT_PULLUP);

}

long calc_step(long msec) {//4096*时间/（时间调和参数（1MIN）*5（5min））==步角/5min
  return STEPS_PER_ROTATION * msec / MILLIS_PER_MIN / RATIO;//yxc:4096脉冲代表一转，返回脉冲数/5min
}

void loop() {
  static long prev_msec, prev_pos;
  long msec, pos;

  if(digitalRead(16) == LOW) {//yxc:低电平就直接旋转
    delaytime = 2; //fast rotation
    rotate(20);
    delaytime = 20; // resume
    return;    
  }
  //电机脉冲计算防止溢出（芯片开启时间%65536）
  msec = millis() % LAP;
  if(msec < prev_msec) { // Laps around yxc：防止小-大
      msec += LAP; // hide lap around temporarily
    }
    
  if(msec >= prev_msec + ROTATION_PERIOD_IN_MSEC) { // do rotation yxc：大于10000再执行旋转
    pos = calc_step(msec);
    rotate(pos - prev_pos);//yxc：旋转对应的脉冲

    if(msec >= LAP) { // Laps around yxc：
      msec %= LAP;
      pos = calc_step(msec);
    } 
    prev_pos = pos;
    prev_msec = msec;
  }
}
